{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 线程替代方案\n",
    "- subprocess\n",
    "    - 完全跳过线程，使用进程\n",
    "    - 是派生进程的主要替代方案\n",
    "- multiprocessing\n",
    "    - 使用threading接口派生，使用子进程\n",
    "    - 允许为多核或者多cpu派生进程，接口跟threading非常相似\n",
    "- concurrent.futures\n",
    "    - 新的异步执行模块\n",
    "    - 任务级别的操作"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 多进程\n",
    "- 程序执行一次就有了一个进程，运行多次就是多进程，像开两个QQ\n",
    "- 进程间通讯（InterprocessCommunication，IPC）\n",
    "- 进程之间无任何共享状态\n",
    "- 进程的创建"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The time is Tue Oct 16 13:23:03 2018 \n"
     ]
    }
   ],
   "source": [
    "# 直接生成Process实例对象，案例\n",
    "import multiprocessing\n",
    "from time import ctime, sleep\n",
    "\n",
    "def clock(interval):\n",
    "    print('The time is %s ' % ctime())\n",
    "    sleep(interval)\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    p = multiprocessing.Process(target=clock, args=(5, ))\n",
    "    p.start()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The time is Tue Oct 16 13:31:00 2018 \n"
     ]
    }
   ],
   "source": [
    "# \n",
    "import multiprocessing\n",
    "from time import ctime, sleep\n",
    "\n",
    "class ClockProcess(multiprocessing.Process):\n",
    "    '''\n",
    "    两个函数比较重要\n",
    "    1. init构造函数\n",
    "    2. run函数\n",
    "    '''\n",
    "    def __init__(self, interval):\n",
    "        super().__init__()\n",
    "        self.interval = interval\n",
    "    \n",
    "    def run(self):\n",
    "        print('The time is %s ' % ctime())\n",
    "        sleep(self.interval)\n",
    "        \n",
    "if __name__ == '__main__':\n",
    "    p = ClockProcess(3)\n",
    "    p.start()\n",
    "        "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 在os中查看pid,ppid以及他们的关系"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "main line\n",
      "module name:  __main__\n",
      "parent process:  <built-in function getppid>\n",
      "process id:  <built-in function getpid>\n",
      "function f\n",
      "module name:  __main__\n",
      "parent process:  <built-in function getppid>\n",
      "process id:  <built-in function getpid>\n",
      "hello bob\n"
     ]
    }
   ],
   "source": [
    "from multiprocessing import Process\n",
    "import os\n",
    "\n",
    "def info(title):\n",
    "    print(title)\n",
    "    print('module name: ', __name__)\n",
    "    # 得到父亲进程的id\n",
    "    print('parent process: ', os.getppid)\n",
    "    # 得到本身进程id\n",
    "    print('process id: ', os.getpid)\n",
    "    \n",
    "def f(name):\n",
    "    info('function f')\n",
    "    print('hello', name)\n",
    "    \n",
    "if __name__ == '__main__':\n",
    "    info('main line')\n",
    "    p = Process(target=f, args=('bob', ))\n",
    "    p.start()\n",
    "    p.join()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 生产者消费者模型\n",
    "- JoinableQueue"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "into customer:  Tue Oct 16 13:58:20 2018\n",
      "pull  1 out of q\n",
      "pull  2 out of q\n",
      "pull  3 out of q\n",
      "pull  4 out of q\n",
      " into producter:  Tue Oct 16 13:58:20 2018\n",
      "put 1 into q\n",
      "put 2 into q\n",
      "put 3 into q\n",
      "put 4 into q\n",
      "out of producter:  <built-in function ctime>\n"
     ]
    }
   ],
   "source": [
    "# JoinableQueue案例\n",
    "import multiprocessing\n",
    "from time import ctime\n",
    "\n",
    "def customer(input_q):\n",
    "    print('into customer: ', ctime())\n",
    "    while True:\n",
    "        # 处理项\n",
    "        item = input_q.get()\n",
    "        print('pull ', item, 'out of q') # 此处替换为有用的工作\n",
    "        input_q.task_done() # 发出信号通知任务完成\n",
    "    print('out of customer: ', ctime()) # 此句未执行，因为q.join()收集到四个task_done（）信号后，主进程未启动，未等到print此句\n",
    "    \n",
    "def producter(sequence, output_q):\n",
    "    print(' into producter: ', ctime())\n",
    "    for item in sequence:\n",
    "        output_q.put(item)\n",
    "        print('put', item, 'into q')\n",
    "    print('out of producter: ', ctime)\n",
    "    \n",
    "if __name__ == '__main__':\n",
    "    q = multiprocessing.JoinableQueue()\n",
    "    cons_p = multiprocessing.Process(target=customer, args=(q, ))\n",
    "    cons_p.daemon = True\n",
    "    cons_p.start()\n",
    "    \n",
    "    # 生产多个项，swqueue代表要发送给消费者的项序列\n",
    "    # 在实践中，这可能是生成器的输出或通过一些其他方式生产出来\n",
    "    sequence = [1,2,3,4]\n",
    "    producter(sequence, q)\n",
    "    q.join()\n",
    "        "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
